package sk.mka.phd.googleagent.statistics;

import java.io.BufferedWriter;
import java.io.IOException;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.logging.Level;
import org.apache.log4j.Logger;
import sk.mka.phd.files.reader.load.arbitrary.ArbitraryDataLoadFileImpl;
import sk.mka.phd.googleagent.config.MavenSingletonConfig;
import sk.mka.phd.googleagent.ngram.AbstactAgent;
import sk.mka.phd.googleagent.query.IGoogleQuery;
import sk.mka.utils.files.writer.BufferFileWriter;
import sk.mka.utils.tools.filesystem.FileUtils;

/**
 * TODO should be rewritten to SINGLETON 
 * @author katrami
 * @date Dec 9, 2010
 */
public class AbstractStatisticsAgent extends AbstactAgent implements IGoogleStatisticsAgent {

    private static final Logger log = Logger.getLogger(AbstractStatisticsAgent.class);
    private final String CONFIG_FILENAME = "target/classes/googleagent-statistics.properties";
    protected MavenSingletonConfig config = MavenSingletonConfig.getInstance(CONFIG_FILENAME);
    public String refusedWordsFromDictionary;
    public String dictionaryOutput;
    public String dictionaryInput;
    public String sleepTime;
    public String ngramOutputFileName;
    public int ngram;
    public boolean writeRefusedWordsFromDictionary;
    protected static int statisticsId;
    protected IGoogleQuery query;
    protected Integer timeSleeping;
    protected static final String separator = " ";

    public AbstractStatisticsAgent() {
        ngram = Integer.valueOf(config.getEnviroment().getProperty("ngram"));
        sleepTime = config.getEnviroment().getProperty("sleepTime");
        String x = config.getEnviroment().getProperty("writeRefusedWordsFromDictionary");
        writeRefusedWordsFromDictionary = Boolean.valueOf(x);
        this.ngramOutputFileName = config.getEnviroment().getProperty("ngramOutputFileName");
        // remove ngram output file
        dictionaryInput = config.getEnviroment().getProperty("dictionaryInput");
        FileUtils.delete(ngramOutputFileName);
        refusedWordsFromDictionary = config.getEnviroment().getProperty("refusedWordsFromDictionary");
        FileUtils.delete(refusedWordsFromDictionary);

        try {
            bufferOutput = BufferFileWriter.openFileForWriting(ngramOutputFileName, true);
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(AbstractStatisticsAgent.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void getStatistics(final String inputFilename) {
        dictionaryInput = config.getEnviroment().getProperty(inputFilename);
        squareDataLoadFile = new ArbitraryDataLoadFileImpl(dictionaryInput, separator);
        squareDataLoadFile.loadData();

        try {
            for (int i = 0; i < squareDataLoadFile.getLines().size(); i++) {
                ArrayList line = (ArrayList) squareDataLoadFile.getLines().get(i);
                getStatistic(line, bufferOutput);
            }
        } catch (Exception e) {
            log.fatal(e);
        } finally {
            try {
                bufferOutput.close();
            } catch (IOException ex) {
                log.error(ex.getMessage());
            }
        }
    }

    public final boolean getStatistic(final ArrayList line, BufferedWriter bufferOutput) {
        boolean bReturn = Boolean.FALSE;
        try {
            timeSleeping = Integer.valueOf(sleepTime);
            final StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("\"");
            for (int j = 0; j < line.size(); j++) {
                final String w = (String) line.get(j);
                stringBuffer.append(w);
                if (j < line.size() - 1) {
                    stringBuffer.append(" "); //append &nbsp
                }
            }
            stringBuffer.append("\"");
            String word = stringBuffer.toString();
            String result;
            Thread.sleep(timeSleeping);
            result = query.makeQuery(word);
            if (result != null) {
                word = word.replace("\"", "");
                bufferOutput.append(word + "\t" + result);
                bufferOutput.newLine();
                bReturn = Boolean.TRUE;
            }
            return bReturn;
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(AbstractStatisticsAgent.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ex) {
            java.util.logging.Logger.getLogger(AbstractStatisticsAgent.class.getName()).log(Level.SEVERE, null, ex);
        }
        return bReturn;
    }

    public boolean getStatistic(final ArrayList line, BufferedWriter bufferOutput, BufferedWriter refusedOutput) {
        AbstractStatisticsAgent.statisticsId++;
        timeSleeping = Integer.valueOf(sleepTime);
        boolean bReturn = Boolean.FALSE;
        final StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("\"");
        for (int j = 0; j < line.size(); j++) {
            final String w = (String) line.get(j);
            stringBuffer.append(w);
            if (j < line.size() - 1) {
                stringBuffer.append(" "); //append &nbsp
            }
        }
        stringBuffer.append("\"");
        String word = stringBuffer.toString();
        String result;
        try {
            Thread.sleep(timeSleeping);
            result = this.query.makeQuery(word);
            if (result != null) {
                BigInteger reallyBig = new BigInteger(result);
                if (reallyBig.intValue() > 0) {
                    word = word.replace("\"", ""); //remove " from word
                    bufferOutput.append(word + "\t" + result);
                    bufferOutput.newLine();
                    bReturn = Boolean.TRUE;
                }
            }
            if (!bReturn && refusedOutput != null) {
                word = word.replace("\"", ""); //remove " from word
                refusedOutput.write(word + "\n");
            }
        } catch (InterruptedException ex) {
            log.fatal(ex);
        } catch (MalformedURLException e) {
            log.fatal(e.getMessage());
        } catch (IOException e) {
            log.fatal(e.getMessage());
        }
        return bReturn;
    }
}
